﻿/****************************************************************************
Copyright (c) 2014-2015 凌惊雪 微信:Lingjingxue 邮箱:lingjingxue@sina.com QQ:271487457

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

using ServerBase.LunarSocket;
using ServerBase.Protocol;
using UtilLib;
using static ServerBase.Config.Conf;
using static ServerBase.Service.BaseDispatch;
using static UtilPublic.Redis.ServerRedis;
using ServerGame.Service;
using System.Collections.Generic;
using UtilPublic.ServerLoger;
using ServerBase.Service;
using ServerBase.Config;
using static ServerGame.Service.Dispatcher;
using ServerBase.Client;
using ServerBase.Other;
using System;
using ServerGame.GameObject;
using ServerPublic.Manager;
using UtilPublic.Serialization;
using ServerPublic.DataBaseMysql;
using ServerPublic.Data;
using ServerGame.Data;
using System.Linq;

namespace ServerGame.Manager
{
    /// <summary>
    /// 管理 邮件
    /// </summary>
    public static class MailMgr
    {
        public static readonly int 玩家邮件数目上限 = EGlobalId.玩家邮件数目上限.ValueInt();
        public static readonly int 玩家邮件未读保留天数 = EGlobalId.玩家邮件未读保留天数.ValueInt();
        public static readonly int 玩家邮件已读保留天数 = EGlobalId.玩家邮件已读保留天数.ValueInt();
        //添加邮件
        public static void MailAdd(this Player player, Mail mail)
        {
            mail.Uid = IdMgr.CreateMailId();
            while (player.DaMail.SortDictMails.Count >= 玩家邮件数目上限)
            {
                player.DaMail.SortDictMails.Remove(player.DaMail.SortDictMails.First().Key);
            }
            player.DaMail.SortDictMails[mail.Uid] = mail;
        }

        #region 信息扩展
        //邮件信息
        public static CLS_MailInfo MailInfo(this Mail mail)
        {
            return new CLS_MailInfo()
            {
                Id = mail.Uid,
                MailType = mail.MailType,
                Title = mail.Title,
                HasAttachments = mail.HasAttachments,
                Readed = mail.Readed,
                Got = mail.Got,
                Saved = mail.Saved,
                CreateTime = mail.CreateTime,
                Sended = mail.Sended,
                ReceiveName = mail.ReceiveName,
                SenderName = mail.SenderName,
            };
        }
        //邮件信息 详细
        public static CLS_MailInfoDetails MailInfoDetails(this Mail mail)
        {
            var result = new CLS_MailInfoDetails()
            {
                Id = mail.Uid,
                MailInfo = mail.MailInfo(),
                Body = mail.Body,
            };
            result.listAward = mail.Attachments;
            return result;
        }
        //邮件信息
        public static CLS_GtMail MailInfoGtMail(this Mail mail)
        {
            return new CLS_GtMail()
            {
                Uid = mail.Uid,
                MailType = mail.MailType,
                Title = mail.Title,
                Body = mail.Body,
                SenderName = mail.SenderName,
                AllTimeReceive = mail.AllTimeReceive,
                CreateTime = mail.CreateTime.ToString(),
                ListAttachments = mail.Attachments,
            };
        }
        #endregion

        #region 玩家邮件扩展
        //获取 邮件列表
        public static void MailList(this Player player, ref List<CLS_MailInfo> result)
        {
            foreach (var item in player.DaMail.SortDictMails.Values)
            {
                result.Add(item.MailInfo());
            }
        }
        //邮件读取
        public static CLS_MailInfoDetails MailRead(this Player player, long uid)
        {
            var item = player.DaMail.SortDictMails[uid];
            item.Readed = true;
            return item.MailInfoDetails();
        }
        //邮件删除
        public static bool MailDelete(this Player player, long uid)
        {
            return player.DaMail.SortDictMails.Remove(uid);
        }
        //邮件清理已读
        public static void MailDeleteReaded(this Player player, short mailtype)
        {
            List<long> listdelete = new List<long>();
            foreach (var item in player.DaMail.SortDictMails.Values)
            {
                if (!item.Readed)
                {
                    continue;
                }
                if (!item.Got && item.HasAttachments)
                {
                    continue;
                }
                listdelete.Add(item.Uid);
            }
            player.DaMail.SortDictMails.RemoveAll(listdelete);
        }
        //邮件保存/取消保存
        public static bool MailSave(this Player player, long uid)
        {
            var item = player.DaMail.SortDictMails[uid];
            item.Readed = true;
            item.Saved = !item.Saved;
            return item.Saved;
        }
        #endregion

        #region 邮件扩展
        //获取克隆
        public static Mail Clone(this Mail mail)
        {
            var result = new Mail()
            {
                Uid = mail.Uid,
                MailType = mail.MailType,
                Title = mail.Title,
                Body = mail.Body,
                SenderName = mail.SenderName,
                CreateTime = mail.CreateTime,
                Readed = mail.Readed,
                Got = mail.Got,
                Saved = mail.Saved,
                Sended = mail.Sended,
                ReceiveName = mail.ReceiveName,
                ActionSource = mail.ActionSource,
                AllTimeReceive = mail.AllTimeReceive,
            };
            foreach (var item in mail.Attachments)
            {
                result.Attachments.Add(item.Clone());
            }
            return result;
        }
        //判断邮件是否过期 //邮件列表中未查看的邮件会保留30天，已查看的邮件会保留3天，超出保存时间的邮件会被立即从列表中清除
        public static bool IsOverdue(this Mail mail)
        {
            if (mail.Readed)
            {
                return ((DateTime.Now - mail.CreateTime) >= TimeSpan.FromDays(玩家邮件已读保留天数));
            }
            else
            {
                return ((DateTime.Now - mail.CreateTime) >= TimeSpan.FromDays(玩家邮件未读保留天数));
            }
        }
        //邮件领取
        public static void MailGet(this Mail mail)
        {
            mail.Readed = true;
            mail.Got = true;
        }
        //邮件尝试领取
        public static void MailGetTry(this Mail mail, ref List<CLS_AwardItem> listAward)
        {
            if (!mail.Got)
            {
                foreach (var att in mail.Attachments)
                {
                    listAward.Add(att.Clone());
                }
            }
            mail.Readed = true;
        }
        #endregion

        #region 附件扩展
        //添加附件
        public static void AddAttachments(this Mail mail, CLS_AwardItem att)
        {
            mail.Attachments.Add(att.Clone());
            mail.Got = !(mail.Attachments.Count > 0);
        }
        //添加附件
        public static void AddAttachments(this Mail mail, List<CLS_AwardItem> att)
        {
            if (att == null)
            {
                return;
            }
            foreach (var item in att)
            {
                mail.Attachments.Add(item.Clone());
            }
            mail.Got = !(mail.Attachments.Count > 0);
        }
        #endregion

        #region 生成邮件
        //GM邮件
        public static Mail MailCreate(this CLS_GtMail MailInfo)
        {
            var result = new Mail()
            {
                Uid = MailInfo.Uid,
                MailType = MailInfo.MailType,
                CreateTime = MailInfo.CreateTime.ToDateTime(),
                Title = MailInfo.Title,
                Body = MailInfo.Body,
                SenderName = MailInfo.SenderName,
                AllTimeReceive = MailInfo.AllTimeReceive,
                ActionSource = EActionSource.邮件GM,
            };
            result.AddAttachments(MailInfo.ListAttachments);
            return result;
        }
        //玩家发送邮件
        public static Mail MailCreate(this CLS_MailInfoSend MailInfo)
        {
            var result = new Mail()
            {
                CreateTime = DateTime.Now,
                MailType = MailInfo.MailType,
                Title = MailInfo.Title,
                Body = MailInfo.Body,
                SenderName = MailInfo.SenderName,
            };
            return result;
        }
        //系统生成邮件
        public static Mail MailCreate(string _Title
            , string _Body
            , string _SenderName
            , EActionSource _ActionSource)
        {
            var result = new Mail()
            {
                CreateTime = DateTime.Now,
                MailType = (short)EMailType.系统邮件,
                Title = _Title,
                Body = _Body,
                SenderName = _SenderName,
                ActionSource = _ActionSource,
            };
            return result;
        }
        #endregion

        #region 发送邮件
        // 给玩家发送邮件
        public static void MailToPlayer(Player player, Mail mail, bool nodify = true)
        {
            mail.ReceiveName = player.Name;
            player.MailAdd(mail);
            if (nodify)
            {
                player.InfoAll();
            }
            player.SaveOffline();
            (ERecordType.邮件系统发送, mail.ActionSource).Rec(player.Uid, mail.Title, mail.Body, Jsh.Jstr(mail.Attachments));

        }
        // 给玩家发送邮件
        public static void MailToPlayer(long Puid, Mail mail, bool nodify = true)
        {
            if (DataGame.GetPlayer(Puid, out var player))
            {
                MailToPlayer(player, mail, nodify);
            }
            else
            {
                (ERecordType.邮件系统发送失败, mail.ActionSource).Rec(Puid, mail.Title, mail.Body, Jsh.Jstr(mail.Attachments));
            }
        }
        // 给玩家发送邮件
        public static void MailToPlayer(long Puid
            , EMailText Title
            , string Body
            , EMailText SenderName
            , EActionSource ActionSource
            , List<CLS_AwardItem> ListAttachments
            , bool nodify = true)
        {
            var mail = MailCreate(Title.TextMail(), Body, SenderName.TextMail(), ActionSource);
            mail.AddAttachments(ListAttachments);
            MailToPlayer(Puid, mail, nodify);
        }
        #endregion

        //更新获取全局邮件
        public static void LoopPlayerMinite1(Player player)
        {
            更新获取全局邮件(player);
        }
        public static void 更新获取全局邮件(Player player)
        {
            var dtNow = DateTime.Now;
            //检查同步版本号
            //2019年3月5日16:26:24 修改  因为要随时检查定时邮件 所以去掉了版本号检查
            //if (player.DaMail.GlobalMailsVersion != DataGlobal.GlobalMailsVersion)
            {
                //去除不在全局列表里的ID
                int 删除数目 = player.DaMail.ListGlobalMailsGeted.RemoveAll(it => (!DataGame.DictGlobalMails.ContainsKey(it)));
                bool 有变化 = 删除数目 > 0;
                //添加新邮件到玩家邮箱
                foreach (var item3 in DataGame.DictGlobalMails.Values)
                {
                    bool 需要添加 = true;
                    //已添加
                    if (player.DaMail.ListGlobalMailsGeted.Contains(item3.Uid))
                    {
                        需要添加 = false;
                    }
                    //未到时
                    if (dtNow < item3.CreateTime)
                    {
                        需要添加 = false;
                    }
                    if (需要添加)
                    {
                        player.DaMail.ListGlobalMailsGeted.Add(item3.Uid);
                        if (item3.AllTimeReceive || item3.CreateTime.Ticks >= player.DaMisc.TicksRegister)
                        {
                            var mail = item3.Clone();
                            player.MailAdd(mail);
                            有变化 = true;
                        }
                    }
                }
                player.DaMail.GlobalMailsVersion = DataGame.GlobalMailsVersion;

                if (有变化)
                {
                    player.InfoAll();
                }
            }
        }



        //小时更新 1 
        public static void LoopPlayerHour1(Player player)
        {
            //清除过期邮件
            player.DaMail.SortDictMails.RemoveAll(it => it.Value.IsOverdue());
        }




    }
}